package com.codefalse.mybatis.generator.util;

import com.codefalse.mybatis.generator.model.ConfigModel;
import com.codefalse.mybatis.generator.model.GenerateConfigModel;
import com.codefalse.mybatis.generator.model.TableModel;
import org.mybatis.generator.config.*;

import java.util.List;

/**
 * @author songxiangfeng
 * Created At 2020-01-19 12:56
 */
public class GenerateUtils {

    public static Configuration buildConfiguration(ConfigModel configModel, GenerateConfigModel generateConfigModel) {
        Configuration config = new Configuration();
        //context
        Context context = new Context(ModelType.CONDITIONAL);
        context.setId(configModel.getDatabase());
        context.setTargetRuntime(generateConfigModel.getTargetRuntime());
        context.setJava8Targeted(true);

        context.addProperty("javaFileEncoding", "UTF-8");
        context.addProperty("beginningDelimiter", "`");
        context.addProperty("endingDelimiter", "`");

        //插件
        //删除注释，修复xml合并问题
        if (generateConfigModel.getSuppressAllComments()) {
            addPlugin(context, "org.mybatis.generator.plugins.UnmergeableXmlMappersPlugin");
        }
        //是否序列化
        if (generateConfigModel.getSupportSerial()) {
            addPlugin(context, "org.mybatis.generator.plugins.SerializablePlugin");
        }
        //是否应用Lombok
        if (generateConfigModel.getSupportLombok()) {
            addPlugin(context, "com.softwareloop.mybatis.generator.plugins.LombokPlugin");
        }
        //是否应用mapper注解
        if (generateConfigModel.getAnnotationMapper()) {
            addPlugin(context, "org.mybatis.generator.plugins.MapperAnnotationPlugin");
        }

        //JavaTypeResolve
        JavaTypeResolverConfiguration resolverConfiguration = new JavaTypeResolverConfiguration();
        resolverConfiguration.setConfigurationType("com.codefalse.mybatis.generator.config.CodefalseJavaTypeResolver");
        resolverConfiguration.addProperty("useJSR310Types", "true");
        context.setJavaTypeResolverConfiguration(resolverConfiguration);

        //JDBC
        JDBCConnectionConfiguration connectionConfiguration = new JDBCConnectionConfiguration();
        connectionConfiguration.setDriverClass("com.mysql.jdbc.Driver");
        connectionConfiguration.setConnectionURL(configModel.packageJDBCUrl());
        connectionConfiguration.setUserId(configModel.getUsername());
        connectionConfiguration.setPassword(configModel.getPassword());
        context.setJdbcConnectionConfiguration(connectionConfiguration);

        //Model
        JavaModelGeneratorConfiguration modelGeneratorConfiguration = new JavaModelGeneratorConfiguration();
        modelGeneratorConfiguration.setTargetProject(generateConfigModel.getProjectPath() + generateConfigModel.getJavaPath());
        modelGeneratorConfiguration.setTargetPackage(generateConfigModel.getModelPackage());
        context.setJavaModelGeneratorConfiguration(modelGeneratorConfiguration);
        //Mapper
        JavaClientGeneratorConfiguration clientGeneratorConfiguration = new JavaClientGeneratorConfiguration();
        clientGeneratorConfiguration.setConfigurationType("XMLMAPPER");
        clientGeneratorConfiguration.setTargetProject(generateConfigModel.getProjectPath() + generateConfigModel.getJavaPath());
        clientGeneratorConfiguration.setTargetPackage(generateConfigModel.getMapperPackage());
        context.setJavaClientGeneratorConfiguration(clientGeneratorConfiguration);
        //XML
        SqlMapGeneratorConfiguration sqlMapGeneratorConfiguration = new SqlMapGeneratorConfiguration();
        sqlMapGeneratorConfiguration.setTargetProject(generateConfigModel.getProjectPath() + generateConfigModel.getResourcePath());
        sqlMapGeneratorConfiguration.setTargetPackage(generateConfigModel.getXmlPackage());
        context.setSqlMapGeneratorConfiguration(sqlMapGeneratorConfiguration);
        //Comment
        CommentGeneratorConfiguration commentGeneratorConfiguration = new CommentGeneratorConfiguration();
        commentGeneratorConfiguration.setConfigurationType("com.codefalse.mybatis.generator.CodefalseCommentGenerator");
        commentGeneratorConfiguration.addProperty("suppressAllComments", generateConfigModel.getSuppressAllComments().toString());
        commentGeneratorConfiguration.addProperty("addRemarkComments", "true");
        context.setCommentGeneratorConfiguration(commentGeneratorConfiguration);
        //Tables
        List<TableModel> tableModels = generateConfigModel.getTableModelList();
        for (TableModel tableModel : tableModels) {
            TableConfiguration tc = new TableConfiguration(context);
            tc.setDelimitIdentifiers(true);
            tc.setAllColumnDelimitingEnabled(true);
            //主键
            if (tableModel.getPrimaryKey() != null && !tableModel.getPrimaryKey().equals("")) {
                tc.setGeneratedKey(new GeneratedKey(
                        tableModel.getPrimaryKey(),
                        "JDBC",
                        true, ""));
            }
            tc.setTableName(tableModel.getTable());
            //dml
            tc.setInsertStatementEnabled(tableModel.isEnableInsert());
            tc.setDeleteByPrimaryKeyStatementEnabled(tableModel.isEnableDelete());
            tc.setUpdateByPrimaryKeyStatementEnabled(tableModel.isEnableUpdate());
            tc.setSelectByPrimaryKeyStatementEnabled(tableModel.isEnableSelect());
            //Example
            tc.setCountByExampleStatementEnabled(tableModel.isExampleCount());
            tc.setDeleteByExampleStatementEnabled(tableModel.isExampleDelete());
            tc.setSelectByExampleStatementEnabled(tableModel.isExampleSelect());
            tc.setUpdateByExampleStatementEnabled(tableModel.isExampleUpdate());

            context.addTableConfiguration(tc);
        }


        config.addContext(context);

        return config;
    }

    private static void addPlugin(Context context, String type) {
        PluginConfiguration plugin = new PluginConfiguration();
        plugin.addProperty("type", type);
        plugin.setConfigurationType(type);
        context.addPluginConfiguration(plugin);
    }

}
